package com.gs.netty.support.handler;


import com.gs.netty.core.annotation.CommandController;
import com.gs.netty.core.annotation.CommandMapping;
import com.gs.netty.core.common.CommandConstants;
import com.gs.netty.support.handler.method.AbstractHandlerMapping;
import com.gs.netty.core.handler.method.CommandMappingInfo;
import com.gs.netty.core.handler.method.HandlerMethod;


import com.gs.netty.websocket.remoting.req.SocketRequest;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;


public class SocketAnnotationCommandMappingHandlerMapping extends AbstractHandlerMapping<SocketRequest, ChannelHandlerContext, CommandMappingInfo> {


   private  HandlerMethod defaultHandler = new HandlerMethod() ;




   @Override
   public boolean support(Object o) {
      return SocketRequest.class.isAssignableFrom(o.getClass());
   }



   @Override
   protected boolean isHandler(Class<?> beanType) {
      // 判断是否有这个注解
      return (AnnotatedElementUtils.hasAnnotation(beanType, CommandController.class));
   }

   @Override
   protected HandlerMethod getDefaultHandler(SocketRequest webSocketRequest) {
      for (String interiorCommand : CommandConstants.INTERIOR_COMMANDS) {
         if(interiorCommand.equals(webSocketRequest.getCommand())){

            return defaultHandler;
         }
      }
      return null;
   }

   @Override
   protected HandlerMethod getHandlerInternal(SocketRequest request) {

      String lookupCommand = request.getCommand();

     return doGetHandler(lookupCommand,request);
   }



   @Override
   protected Set<String> getDirectPaths(CommandMappingInfo mapping) {
      Set<String> command = mapping.getCommand();
      return command;
   }

   @Nullable
   protected CommandMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
       // 创建注解消息对象
       return createRequestMappingInfo(method);
   }

   @Nullable
   private CommandMappingInfo createRequestMappingInfo(AnnotatedElement element) {
      // 获取注解
      CommandMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, CommandMapping.class);

      if (requestMapping == null) {
         return null;
      }
      String value = requestMapping.value();
      HashSet<String> commandSet = new HashSet<>();

      if (StringUtils.hasText(value)) {
         commandSet.add(value);
      }



      return new CommandMappingInfo(commandSet,requestMapping.serializable().name(),requestMapping.weight(),null);
   }
}
